﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace Nomo.UnityLegacyInputModule
{
    /// <summary>
    /// 处理输入事件的工具类。
    /// </summary>
    public static class Input
    {
        private static readonly RuntimePlatform Platform = Application.platform;
        private static readonly List<Touch>     Touches  = new List<Touch>(1 << 4);
        private static          int             _frameCount;

        /// <summary>
        /// 指针位置。
        /// </summary>
        /// <param name="index">（在允许多个指针同时输入的平台上的）指针的索引。</param>
        /// <returns>指针位置。</returns>
        public static Vector2 Position(int index)
        {
            RefreshTouches();

            switch (Platform)
            {
                case RuntimePlatform.OSXEditor:
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.OSXPlayer:
                case RuntimePlatform.WindowsPlayer:
                case RuntimePlatform.WebGLPlayer:
                    return UnityEngine.Input.mousePosition;
                case RuntimePlatform.IPhonePlayer:
                case RuntimePlatform.Android:
                    try
                    {
                        return Touches[index].position;
                    }
                    catch (Exception)
                    {
                        return default;
                    }
                default:
                    return Vector2.zero;
            }
        }

        /// <summary>
        /// 指针数量。
        /// </summary>
        /// <returns>指针数量。</returns>
        public static int Count()
        {
            RefreshTouches();

            switch (Platform)
            {
                case RuntimePlatform.OSXEditor:
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.OSXPlayer:
                case RuntimePlatform.WindowsPlayer:
                case RuntimePlatform.WebGLPlayer:
                    return UnityEngine.Input.GetMouseButton(0) || UnityEngine.Input.GetMouseButton(1) ? 1 : 0;
                case RuntimePlatform.IPhonePlayer:
                case RuntimePlatform.Android:
                    return Touches.Count;
                default:
                    return 0;
            }
        }

        /// <summary>
        /// 如果当前程序运行在 iOS 或 Android 平台上，返回 <paramref name="position"/> 是否是索引为 <paramref name="index"/> 的指针的位置；否则，返回 <see langword="true"/> .
        /// </summary>
        /// <param name="index"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public static bool IsSpecificIndexesInput(int index, Vector2 position)
        {
            RefreshTouches();

            switch (Platform)
            {
                case RuntimePlatform.IPhonePlayer:
                case RuntimePlatform.Android:
                    try
                    {
                        return Touches[index].position == position;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                default:
                    return true;
            }
        }

        /// <summary>
        /// 指针接触屏幕。
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public static bool Down(int index)
        {
            RefreshTouches();

            switch (Platform)
            {
                case RuntimePlatform.OSXEditor:
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.OSXPlayer:
                case RuntimePlatform.WindowsPlayer:
                case RuntimePlatform.WebGLPlayer:
                    return UnityEngine.Input.GetMouseButtonDown(index);
                case RuntimePlatform.IPhonePlayer:
                case RuntimePlatform.Android:
                    try
                    {
                        return Touches[index].phase == TouchPhase.Began;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                default:
                    return false;
            }
        }

        /// <summary>
        /// 指针离开屏幕。
        /// </summary>
        public static bool Up(int index)
        {
            RefreshTouches();

            switch (Platform)
            {
                case RuntimePlatform.OSXEditor:
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.OSXPlayer:
                case RuntimePlatform.WindowsPlayer:
                case RuntimePlatform.WebGLPlayer:
                    return UnityEngine.Input.GetMouseButtonUp(index);
                case RuntimePlatform.IPhonePlayer:
                case RuntimePlatform.Android:
                    try
                    {
                        return Touches[index].phase == TouchPhase.Ended;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                default:
                    return false;
            }
        }

        /// <summary>
        /// 指针摁在屏幕上。
        /// </summary>
        public static bool HeldDown(int index)
        {
            RefreshTouches();

            switch (Platform)
            {
                case RuntimePlatform.OSXEditor:
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.OSXPlayer:
                case RuntimePlatform.WindowsPlayer:
                case RuntimePlatform.WebGLPlayer:
                    return UnityEngine.Input.GetMouseButton(index) && !UnityEngine.Input.GetMouseButtonDown(index) && !UnityEngine.Input.GetMouseButtonUp(index);
                case RuntimePlatform.IPhonePlayer:
                case RuntimePlatform.Android:
                    try
                    {
                        var phase = Touches[index].phase;
                        return phase == TouchPhase.Moved || phase == TouchPhase.Stationary;
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                default:
                    return false;
            }
        }

        private static void RefreshTouches()
        {
            if (_frameCount != Time.frameCount)
                switch (Platform)
                {
                    case RuntimePlatform.Android:
                    case RuntimePlatform.IPhonePlayer:
                        _frameCount = Time.frameCount;
                        Touches.Clear();
                        Touches.AddRange(UnityEngine.Input.touches);
                        break;
                }
        }
    }
}
